﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml;

using Formatting = Newtonsoft.Json.Formatting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Kwan.Web
{
    // Comments are Copyright (c) 2007 James Newton-King
    /// <summary>
    /// Convenience wrappers for Json.NET
    /// </summary>
    public partial class JSON
    {
        public static string ExtResult(string flag, string result)
        {
            return ("{\"success\":" + flag + ",\"data\":" + result + "}");
        }

        public static string ExtGridResult(int total, string data)
        {
            return ("{\"total\":" + total + ",\"data\":" + data + "}");
        }
        /// <summary>
        /// Serializes the specified object to a Json object.
        /// </summary>
        /// <param name="obj">The object to serialize.</param>
        /// <param name="formatting">Format the JSON serialized string.</param>
        /// <param name="converters">A List of JsonConverter objects to customize serialization.</param>
        /// <param name="quoteName">Gets or Sets a value indicating whether object names will be surrounded with quotes.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>A Json string representation of the object.</returns>
        [Description("Serializes the specified object to a Json object.")]
        public static string Serialize(object obj, Formatting formatting)
        {
            return JsonConvert.SerializeObject(obj, formatting, new JsonSerializerSettings
            {
                Converters = new JsonConverter[] { new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter() },
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                NullValueHandling = NullValueHandling.Ignore
            });
        }

        /// <summary>
        /// Serializes the specified object to a Json object.
        /// </summary>
        /// <param name="obj">The object to serialize.</param>
        /// <param name="converters">A List of JsonConverter objects to customize serialization.</param>
        /// <param name="quoteName">Gets or Sets a value indicating whether object names will be surrounded with quotes.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>A Json string representation of the object.</returns>
        [Description("Serializes the specified object to a Json object.")]
        public static string Serialize(object obj)
        {
            return JSON.Serialize(obj, Formatting.None);
        }

        /// <summary>
        /// Serializes the Json object to a specific object.
        /// </summary>
        /// <param name="value">Json object</param>
        /// <param name="type">Object's type</param>
        /// <param name="converters">A List of JsonConverter objects to customize deserialization.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>Object</returns>
        [Description("Serializes the Json object to a specific object.")]
        public static object Deserialize(string value, Type type, List<JsonConverter> converters, IContractResolver resolver)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();

            settings.Converters = converters;

            if (resolver != null)
            {
                settings.ContractResolver = resolver;
            }

            return JsonConvert.DeserializeObject(value, type, settings);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <param name="value">The object to deserialize.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static object Deserialize(string value)
        {
            return JSON.Deserialize(value, null);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <param name="value">The object to deserialize.</param>
        /// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static object Deserialize(string value, Type type)
        {
            return JSON.Deserialize(value, type, null, null);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <param name="value">The object to deserialize.</param>
        /// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static object Deserialize(string value, Type type, IContractResolver resolver)
        {
            return JSON.Deserialize(value, type, null, resolver);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <typeparam name="T">The type of the object to deserialize.</typeparam>
        /// <param name="value">The object to deserialize.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static T Deserialize<T>(string value)
        {
            return (T)JSON.Deserialize(value, typeof(T), null, null);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <typeparam name="T">The type of the object to deserialize.</typeparam>
        /// <param name="value">The object to deserialize.</param>
        /// <param name="converters">A List of JsonConverter objects to customize serialization.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static T Deserialize<T>(string value, List<JsonConverter> converters)
        {
            return (T)JSON.Deserialize(value, typeof(T), converters, null);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <typeparam name="T">The type of the object to deserialize.</typeparam>
        /// <param name="value">The object to deserialize.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static T Deserialize<T>(string value, IContractResolver resolver)
        {
            return (T)JSON.Deserialize(value, typeof(T), resolver);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <typeparam name="T">The type of the object to deserialize.</typeparam>
        /// <param name="value">The object to deserialize.</param>
        /// <param name="converters">A List of JsonConverter objects to customize serialization.</param>
        /// <param name="resolver">The IContractResolver object to customize serialization.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static T Deserialize<T>(string value, List<JsonConverter> converters, IContractResolver resolver)
        {
            return (T)JSON.Deserialize(value, typeof(T), converters, resolver);
        }

        /// <summary>
        /// Deserializes the specified object to a Json object.
        /// </summary>
        /// <param name="value">The object to deserialize.</param>
        /// <returns>The deserialized object from the Json string.</returns>
        [Description("Deserializes the specified object to a Json object.")]
        public static XmlNode DeserializeXmlNode(string value)
        {
            return JsonConvert.DeserializeXmlNode(value);
        }

        //used internally to minimize Converters calling (less memory consumption)
        private static List<JsonConverter> convertersInternal;
    }
}